""" That module will focus on logging the rules into the database
Firstly it parses them and then stores into the database..."""
import datetime

import re
import os
from confplace import LOG_PATH
from confmethods import getlogInfo,setlogInfo
import linecache
#import Constants
from iptables.models import Logs,Prefixer

class Logman(object):
    """ general logging utility"""
    def __init__(self):
       
        #The host name:
        self.hName=""
        self.todaYear=""
        
        #simple process
        self.genCoputation()

        #The compiled re patterns
        self.rePref=re.compile('(.*%s)(.*)(IN=)'%self.hName)
        self.reIN=re.compile('(.*IN=)(.*)(OUT=)')
        self.reOut=re.compile('(.*OUT=)(\w*)(\s*?)')
        self.reSrc=re.compile('(.*SRC=)([\d.]*)(\s*?)')
        self.reDst=re.compile('(.*DST=)([\d.]*)(\s*?)')
        self.reProto=re.compile('(.*PROTO=)(\w*)(\s*?)')
        self.reSpt=re.compile('(.*SPT=)(\d*)(\s*?)')
        self.reDsp=re.compile('(.*DPT=)(\d*)(\s*?)')
        self.reDate=re.compile('(.*)(%s)'%self.hName)

        self.__dbLogBuffer=[]#log buffer to store to db

        main_path=os.getcwdu()
        #print main_path
        if os.path.exists("".join([main_path,"/loginfo.txt"])):
            self.__logInfo=getlogInfo()
        else:
            #reset it
            setlogInfo(1,0)
            self.__logInfo=getlogInfo()
            

        #print self.__logInfo

    def genLine(self):
        """ Takes the line from log file and pass it to be parsed"""
        try:
            #if it is less than stored there is a problem should set tail to 0
            if os.stat(LOG_PATH).st_size<self.__logInfo[1]:
                #if it less than usual should be reset
                self.__logInfo[0]=1 #reset the tail
            #print Constants.LOG_PATH
            linecache.clearcache()
            liner=linecache.getline(LOG_PATH,self.__logInfo[0])
            #print self.__logInfo[0]
            #print liner
            if liner:
                self.parseLine(liner)
            #print "Burda cagir"
            #print liner


            while(liner):
                self.__logInfo[0]+=1
                liner=linecache.getline(LOG_PATH,self.__logInfo[0])
                if liner:
                    #if it reached 50 log entries then store it to db
                    if len(self.__dbLogBuffer)>=50:
                        #print self.__dbLogBuffer
                        ##store the current logs
                        self.logStore()

                    self.parseLine(liner)

            if len(self.__dbLogBuffer)>0:#if there is again something in the buffer
                self.logStore()
                #print self.__dbLogBuffer

            #print "Checkout the database"
            '''
            print "Son olarak ise line ve size yazilcak"
            print "Size :",os.stat(Constants.LOG_PATH).st_size
            print "Line :",self.__logInfo[0]'''
            setlogInfo(self.__logInfo[0],os.stat(LOG_PATH).st_size)

            return 0
        
        except IOError:
            print "Problem with the files"
            return 1

    def getMonth(self,mString):
        """ Give month back as a number to be suitable for database"""
        m={'January':1,
            'February':2,
            'March':3,
            'April':4,
            'May':5,
            'June':6,
            'July':7,
            'August':8,
            'September':9,
            'October':10,
            'November':11,
            'December':12}
        if m.has_key(mString)==True:
            return m[mString]
        else:
            return 1#Ocak eger cokerse


    def genCoputation(self):
        """ Method will make some basic settings
        1.Give back the current year,
        2.Give back the computer name
        3. Delete the logs that are older than defined"""

        x=os.popen3('uname -n')
        self.hName=x[1].read().strip()

        #The year:
        d=str(datetime.datetime(1111,2,2).today())
        result=re.match('(\d*)(-?)',d)
        self.todaYear=result.group(1).strip()

        #deleting old ones
        #self.delOlder()


    def parseLine(self,lstring):
        """ The method parses given string then should store it to the db"""
        self.__dbLogs=[]
        
        #The date part of the code
        result=re.match(self.reDate,lstring)
        if result:
            dt=result.group(1).strip().split()
            mnth=self.getMonth(dt[0])
            #print mnth
            self.__dbLogs.append("".join([str(self.todaYear),"-",str(mnth),"-",dt[1]," ",dt[2]]))

        else:
            self.__dbLogs.append('0000-00-00 00:00:00')

        #The prefix part
        result=re.match(self.rePref,lstring)
        if result:
            if result.group(2).strip()!='':

                self.__dbLogs.append(result.group(2).strip())
            else:
                self.__dbLogs.append('NotSpec')
        else:
            self.__dbLogs.append('bos')

        #the in device
        result=re.match(self.reIN,lstring)
        if result:
            if result.group(2).strip()!='':

                self.__dbLogs.append(result.group(2).strip())
            else:
                self.__dbLogs.append('NotSpec')

        else:
            self.__dbLogs.append('bos')


        #the out device
        result=re.match(self.reOut,lstring)
        if result:
            if result.group(2).strip()!='':

                self.__dbLogs.append(result.group(2).strip())
            else:
                self.__dbLogs.append('NotSpec')
        else:
            self.__dbLogs.append('bos')


        #the src matching
        result=re.match(self.reSrc,lstring)
        if result:
            if result.group(2).strip()!='':

                self.__dbLogs.append(result.group(2).strip())
            else:
                self.__dbLogs.append('NotSpec')
        else:
            self.__dbLogs.append('bos')


        result=re.match(self.reDst,lstring)
        if result:
            if result.group(2).strip()!='':

                self.__dbLogs.append(result.group(2).strip())
            else:
                self.__dbLogs.append('NotSpec')
        else:
            self.__dbLogs.append('bos')

        #The protocol match
        result=re.match(self.reProto,lstring)
        if result:
            if result.group(2).strip()!='':

                self.__dbLogs.append(result.group(2).strip())
            else:
                self.__dbLogs.append('NotSpec')
        else:
            self.__dbLogs.append('bos')

        result=re.match(self.reSpt,lstring)
        if result:
            if result.group(2).strip()!='':

                self.__dbLogs.append(result.group(2).strip())
            else:
                self.__dbLogs.append('NotSpec')
        else:
            #self.__dbLogs.append('bos')
            self.__dbLogs.append(0)

        result=re.match(self.reDsp,lstring)
        if result:
            if result.group(2).strip()!='':

                self.__dbLogs.append(result.group(2).strip())
            else:
                self.__dbLogs.append('NotSpec')
        else:
            #self.__dbLogs.append('bos')
            self.__dbLogs.append(0)

        self.__dbLogBuffer.append(self.__dbLogs)


    def delOlder(self):
        #no use for that method for nowww
        """ That method deletes the log entries that are older than user supplied
        information it is measured in days,if the const info is 2 entries older
        than 2 days will be deleted"""
        #Firstly compute the date date will be deleted
        #The todays date:
        today=datetime.date.today()
        #print "Today is :",today
        todel=today-datetime.timedelta(days=int(Constants.LOG_TIME))
        #print "The date that will be deleted ",todel

        a=str(datetime.datetime(1111,2,3).today()).split()
        x=re.compile('(.*)(\.\w)')
        v=re.match(x, a[1])
        #print v.group(1)
        latest="".join([str(todel)," ",v.group(1)])
        #print latest


        try:

            self.__conn=super(Logman,self).MakeConn()
            self.__cursor=self.__conn.cursor()
            self.__cursor.execute("delete from logs where logDate < %s",(latest))
            self.__cursor.close()
            self.__conn.commit()
            self.__conn.close()
            
            return 0#succes
        
        except MySQLdb.Error,e:
             print "Some error occured in mysql connection..hop.:",e
             return 2 #That time is different because of maxrule


    def logStore(self):
        """ Method stores the logs that are loaded into the buffer to the database
        in the proper order and format. It is done by a external stored procedure"""

        try:
            for logs in self.__dbLogBuffer:
                #print logs[0],logs[1],logs[2],logs[3],logs[4],logs[5],logs[6],logs[7],logs[8]
                
                logs[1]=logs[1].strip()
                res=Prefixer.objects.filter(pref_name=logs[1])
                #burada logs[1] prefixi tuttar 
                if res:
                    #burada yukkle
                    l=Logs(parent_prefix_id=res[0].id,
                           log_date=logs[0],
                           in_dev=logs[2],
                           outDev=logs[3],
                           ip_src=logs[4],
                           ip_dst=logs[5],
                           proto=logs[6],
                           sport=logs[7],
                           dport=logs[8]
                           )
                    
                    #into the database
                    l.save()
                #else kismi yok bisi yapma yani
               
            #clear the buffer
            self.__dbLogBuffer=[]
            
            return 0#succes
        
        except Exception,e:
             print "Some error occured in mysql connection..hop.:",e
             return 2 #That time is different because of maxrule







if __name__=="__main__":
    a=Logman()
    print a.genLine()
    #print a.delOlder()
    #print "Yil :",a.todaYear
    #print "CompName :",a.hName
